package com.quanroon.ysq.queue.delay_queue;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import cn.hutool.core.util.IdUtil;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author quanroong.ysq
 * @version 1.0.0
 * @description 测试延时队列
 * @createtime 2021/9/8 20:49
 */
public class DelayQueueTest {



    public static ThreadFactory threadFactory = new ThreadFactoryBuilder().setNamePrefix("delay-poll-%d").build();
    /**
     * 线程池
     * 核心线程数corePoolSize：5
     */
    public static ExecutorService pool = new ThreadPoolExecutor(5, 500, 0L, TimeUnit.MICROSECONDS,
            new LinkedBlockingDeque<>(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy());

    DelayQueue<DelayInfo> delayQueue = new DelayQueue<>();

    public static void main(String[] args) {
        DelayQueueTest queueTest = new DelayQueueTest();
        for (int i = 1; i < 10; i++) {
            String orderId = IdUtil.simpleUUID();
            //1.向延时队列中增加任务
            queueTest.delayQueue.add(new DelayInfo(orderId, i * 2));
        }

        //2.启动线程，采用线程池来创建线程消费者
        ExecutorService threadPool = Executors.newFixedThreadPool(5);

        queueTest.thread();
       /*for (;;){
           try {
               DelayInfo delayInfo = delayQueue.take();
               pool.execute(new DelayConsumer(delayInfo));
               //threadPool.execute(new DelayConsumer(delayInfo));
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }*/

    }
    public void thread(){
        pool.execute(new Thread(this::startThread));
    }
    public void startThread(){
        for (;;){
            try {
                DelayInfo delayInfo = delayQueue.take();
                //pool.execute(new DelayConsumer(delayInfo));
                //threadPool.execute(new DelayConsumer(delayInfo));

                try {
                    //System.out.println("开始模拟执行任务，假设执行任务消耗了5s，当前时间：" + DateUtil.formatDateTime(new Date()));
                    Thread.sleep(5000);//根据执行任务的时间，如果采用少量则会出现任务执行滞后问题。当上一个任务执行越慢，而延时任务相对集中情况下，就会产生严重的滞后
                    LocalDateTime expireLocal = LocalDateTime.parse(DateUtil.formatDateTime(delayInfo.getExpireTime()), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    Duration between = Duration.between(expireLocal, LocalDateTime.now());
                    System.out.println("任务执行完成：" + delayInfo.toString() +",任务执行耽误时间s："
                            + between.getSeconds());
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}